Reading Quantity Samples

The Scripting app allows you to query quantity-based health data, such as step count, heart rate, body mass, calories burned, distance, and more, using the global Health.queryQuantitySamples() API.

This guide explains how to retrieve quantity samples and work with the results.


What Are Quantity Samples?

A quantity sample represents a numeric health measurement taken at a specific time or over a time interval. Common examples include:

  • stepCount
  • heartRate
  • bodyMass
  • activeEnergyBurned
  • distanceWalkingRunning

These samples can be either discrete (a single measurement) or cumulative (a value summed over time).


API Overview

1Health.queryQuantitySamples(
2  quantityType: HealthQuantityType,
3  options?: {
4    startDate?: Date
5    endDate?: Date
6    limit?: number
7    strictStartDate?: boolean
8    strictEndDate?: boolean
9    sortDescriptors?: Array<{
10      key: "startDate" | "endDate" | "count"
11      order?: "forward" | "reverse"
12    }>
13  }
14): Promise<Array<HealthQuantitySample | HealthCumulativeQuantitySample | HealthDiscreteQuantitySample>>

Parameters

  • quantityType: The health data type to query (e.g., "stepCount", "heartRate")
  • startDate / endDate: Time range for filtering samples
  • limit: Maximum number of results
  • strictStartDate / strictEndDate: If true, only samples starting/ending exactly at those dates will be included
  • sortDescriptors: Optional array to sort results by startDate, endDate, or count

Sample Code: Reading Step Count

1const results = await Health.queryQuantitySamples("stepCount", {
2  startDate: new Date("2025-07-01T00:00:00"),
3  endDate: new Date("2025-07-02T00:00:00"),
4  limit: 10,
5  sortDescriptors: [{ key: "startDate", order: "reverse" }]
6})
7
8for (const sample of results) {
9  const value = sample.quantityValue(HealthUnit.count())
10  console.log(`Steps: ${value} from ${sample.startDate} to ${sample.endDate}`)
11}

Sample Code: Reading Heart Rate with Unit

1const results = await Health.queryQuantitySamples("heartRate", {
2  startDate: new Date(Date.now() - 3600 * 1000), // past hour
3})
4
5for (const sample of results) {
6  const bpm = sample.quantityValue(
7    HealthUnit.count().divided(HealthUnit.minute())
8  )
9  console.log(`Heart Rate: ${bpm} bpm at ${sample.startDate}`)
10}

Interpreting Sample Types

Each sample returned may be:

  • HealthQuantitySample: The base class
  • HealthCumulativeQuantitySample: Includes .sumQuantity(unit)
  • HealthDiscreteQuantitySample: Includes .averageQuantity(unit), .maximumQuantity(unit), etc.

You can use instanceof or feature detection to check for extended properties.

Example:

1if ("averageQuantity" in sample) {
2  const avg = sample.averageQuantity(HealthUnit.count())
3  console.log("Average:", avg)
4}

Notes

  • The unit passed to .quantityValue() must match the type (e.g., use count() for steps, gram(HealthMetricPrefix.kilo) for body mass).
  • Some types (like heart rate) require compound units like count().divided(minute()).
  • The time interval is defined by startDate and endDate on each sample.
  • Samples may have an optional .metadata and .count.

Common Units by Type

Quantity Type Recommended Unit
"stepCount" HealthUnit.count()
"heartRate" HealthUnit.count().divided(HealthUnit.minute())
"bodyMass" HealthUnit.gram(HealthMetricPrefix.kilo)
"activeEnergyBurned" HealthUnit.kilocalorie()
"distanceWalkingRunning" HealthUnit.meter()

Error Handling

1try {
2  const results = await Health.queryQuantitySamples("stepCount")
3  console.log("Sample count:", results.length)
4} catch (err) {
5  console.error("Failed to query samples:", err)
6}

Summary

To read quantity samples:

  1. Call Health.queryQuantitySamples(type, options)
  2. Loop through the results
  3. Use .quantityValue(unit) or .sumQuantity(unit) depending on the type

This API gives you powerful access to time-series health data stored in HealthKit.